package taskrunner

import "time"

//2 dispatcher -> mysql ->videoid->datachannel
//3 exector ->datachannel->videoid->delete videos
//生产者消费者模型
type Runner struct {
	Controller controlChan
	Error      controlChan
	Data       dataChan
	dataSize   int
	longlived  bool //是否要保持数据 方便下次使用
	Dispatcher fn
	Executor   fn
}

func NewRunner(size int, longlived bool, d, e fn) *Runner {
	return &Runner{
		Controller: make(controlChan, 1),
		Error:      make(controlChan, 1),
		Data:       make(dataChan, size),
		dataSize:   size,
		longlived:  longlived,
		Dispatcher: d,
		Executor:   e,
	}
}

//这个生产者消费者模型 不够好，他每次只能执行一个角色，不能一边生产一边消费，
func (r *Runner) startDispatch() {
	defer func() {
		if !r.longlived { //如果不是需要长久保持 就关闭通道
			close(r.Controller)
			close(r.Data)
			close(r.Error)
		}
	}()
	for {
		select {
		case c := <-r.Controller:
			if c == READY_TO_DISPATCH {
				err := r.Dispatcher(r.Data)
				if err != nil {
					r.Error <- CLOSE
				} else {
					r.Controller <- READY_TO_EXECUTE
				}
			} else if c == READY_TO_EXECUTE {
				err := r.Executor(r.Data)
				if err != nil {
					r.Error <- CLOSE
				} else {
					r.Controller <- READY_TO_DISPATCH
				}
			}

		case e := <-r.Error:
			if e == CLOSE {
				return
			}
		default:
			time.Sleep(time.Second)
		}
	}
}
func (r *Runner) StartAll() {
	r.Controller <- READY_TO_DISPATCH
	r.startDispatch()
}
